
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="javax.mail.*,
        javax.jcr.Repository,
        org.apache.jackrabbit.j2ee.RepositoryAccessServlet,
        org.apache.jackrabbit.util.Text,
        javax.jcr.Session,
        javax.jcr.SimpleCredentials,
        javax.jcr.query.Query,
        javax.jcr.query.RowIterator,
        java.text.NumberFormat,
        javax.jcr.query.Row,
        java.security.*,
        java.math.*,
        javax.jcr.Node,
        java.net.URLEncoder,
        java.text.SimpleDateFormat,
        java.text.DateFormat,
        java.util.List,
        java.util.ArrayList,
        java.util.Iterator,
        java.util.HashMap,
        javax.jcr.Value,
        javax.jcr.RepositoryException,
        javax.mail.internet.MimeMessage,
        org.apache.commons.fileupload.*,
        org.apache.commons.fileupload.servlet.*,
        org.apache.commons.fileupload.disk.*,
        org.apache.commons.io.IOUtils,
        java.io.*,
        java.util.zip.*,
        java.util.*,
        java.net.*,
        org.ilookinto.util.NodeUtil,
        java.util.Properties,
        org.ilookinto.util.CloseUtil,
        org.apache.commons.io.IOUtils,
        javax.mail.Message.RecipientType,
        javax.mail.internet.*" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>JSP Page</title>
    <style type="text/css">


      TD {text-align:left};
    </style>
  </head>
  <body>
    <div style="text-align: center; border: 2px" >
      <form>
        <table >
          <tr> <td >
              Account: </td> <td>  <input type="text" name="account" value="elookinto"/> </td> </tr>
          <tr> <td >
              Host: </td> <td>  <input type="text" name="host" value="127.0.0.1"/> </td> </tr>
          <tr> <td >
              Protocol: </td> <td>  <input type="text" name="protocol" value="imap"/> </td> </tr>
          <tr> <td>
              Password: </td> <td>  <input type="password" name="password" value="test"/> </td> </tr>
          <tr> <td>
              Cancel processing: </td> <td>
              <select name="cancel">
                <option value="false">false</option>
                <option value="true">true</option>
              </select>
          <tr> <td>
              <input type="submit" value="Submit" />
            </td> </tr>
        </table>
      </form>
    </div>

    <%  Session jcrSession = null;
        try {
          Repository rep;


          try {
            rep = RepositoryAccessServlet.getRepository(pageContext.getServletContext());
            jcrSession = rep.login(new SimpleCredentials("admin", "admin".toCharArray()));
          } catch (Throwable e) {
    %>
    Error while accessing the repository: <font color="red"><%= Text.encodeIllegalXMLCharacters(e.getMessage())%></font><br>
    Check the configuration or use the <a href="admin/">easy setup</a> wizard.<%
            return;
          }


          String cancel = request.getParameter("cancel");
          if (cancel != null && cancel.equalsIgnoreCase("true")) {
            session.setAttribute("cancel", "true");
            out.println("processing cancelled");
            return;
          }
          String account = request.getParameter("account");
          String password = request.getParameter("password");
          if (account != null && !account.isEmpty() && password != null && !password.isEmpty()) {
            Properties props = new Properties();
            // props.put("mail.from", "user2@mailserver.com");
            javax.mail.Session emailSession = javax.mail.Session.getInstance(props);
            final Store store = emailSession.getStore("imap");
            store.connect("localhost", "elookinto", "elookinto");
            final Folder folder = store.getDefaultFolder().getFolder("inbox");

            //Folder[] list = folder.list();
            // for (Folder f: list)
            // out.println(f.getFullName());
            //if (true) return;
            final HttpSession mySession = session;
            final Session myJcrSession = jcrSession;
            final HttpServletRequest myRequest = request;
            new Thread() {

              public void run() {
                mySession.setAttribute("cancel", "processing");
                processMessage(folder, mySession, myJcrSession, myRequest.getRemoteHost());
                mySession.setAttribute("mm", "Processing finished");
                try {

                  myJcrSession.save();
                } catch (Exception e) {
                  e.printStackTrace();
                }

                myJcrSession.logout();
                CloseUtil.close(folder, store);
              }
            }.start();

            //out.print(folder.getMessage(1).getSubject());
            out.println("Be patient while it is processing." + folder.getFullName());

          }
        } catch (Exception e) {
        } finally {
          if (jcrSession != null) {
            //jcrSession.logout();
          }
        }
    %>

  </body>
</html>


<%!  org.apache.tika.mime.MimeTypes mt = new org.apache.tika.mime.MimeTypes();

  private void processMessage(Folder folder, javax.servlet.http.HttpSession session, Session jcrSession, String remoteHost) {
    if ("true".equals(session.getAttribute("cancel"))) {
      return;
    }
    try {
      folder.open(Folder.READ_ONLY);
      String requestHost = "host-" + remoteHost.replaceAll("[\\.|:]", "-");
      System.out.println(remoteHost + "..."+ requestHost);
      // folder.getMessage(345);
      int count = folder.getMessageCount();
      Node root = jcrSession.getRootNode();
      Node node = NodeUtil.emailNode(requestHost, root);
      for (int i = 1; i <= count; i++) {
        if ("true".equals(session.getAttribute("cancel"))) {
          session.setAttribute("mm", "process status: cancelled;" + folder.getFullName() + ";" + i + " of total " + folder.getMessageCount() + " processed <br/>");
          break;
        }

        try {

          Message mm = folder.getMessage(i);

          MimeMessage m = (MimeMessage) folder.getMessage(i);
          String messageName = "message.txt";

          String id = m.getMessageID();
          if (id == null)  id = java.util.UUID.randomUUID().toString();
          id = MungPass(id);
          if (node.hasNode(id)) {
            node.getNode(id).remove();
          }
          Node folderNode = node.addNode(id, "nt:folder");

          HashMap<String, Object> meta = new HashMap<String, Object>();


          System.out.println(i + " subj " + m.getSubject());
          meta.put("subject", m.getSubject());
          meta.put("message-id", m.getMessageID());
          meta.put("content-id", m.getContentID());
          meta.put("content-md5", m.getContentMD5());
          meta.put("language", m.getContentLanguage());
          meta.put("sent", m.getSentDate());
          meta.put("received", m.getReceivedDate());
          meta.put("from", m.getFrom());
          meta.put("to", m.getRecipients(RecipientType.TO));
          meta.put("cc", m.getRecipients(RecipientType.CC));
          meta.put("bcc", m.getRecipients(RecipientType.BCC));
          meta.put("reply-to", m.getReplyTo());
          meta.put("sender", m.getSender());


          Object content = m.getContent();
          String message = "";
          String messageContentType = "text/plain";
          if (content instanceof String) {
            message = content.toString();
            System.out.println("message----" + message);
          } else {
            Multipart multipart = (Multipart) content;
            //Part 0 is suppose the message body ???? Damn javamail.
            int mCount = multipart.getCount();
            System.out.println("m=" + mCount);
            BodyPart part = multipart.getBodyPart(0);
            Object messagePart = part.getContent();
            if (messagePart instanceof Multipart) {
              System.out.println("here1");
              for (int j = 0; j < ((Multipart) messagePart).getCount(); j++) {
                BodyPart bodyPart = ((Multipart) messagePart).getBodyPart(j);
                messageContentType = bodyPart.getContentType();
                if (messageContentType != null && messageContentType.toLowerCase().contains("html")) {
                  messageName = "message.html";
                }
                message = IOUtils.toString(bodyPart.getInputStream());
                if (message.trim().length() != 0) {
                  break;
                }
              }
               System.out.println("here2");
            } else {
              messageContentType = part.getContentType();
              message = IOUtils.toString(part.getInputStream());
              System.out.println("message---" + message);
              part.getInputStream().close();
            }
            for (int j = 1; j < multipart.getCount(); j++) {
              BodyPart bodyPart = multipart.getBodyPart(j);
              String contentType = bodyPart.getContentType();
              String fileName = bodyPart.getFileName();
              if (contentType == null && fileName != null) {
                contentType = mt.getMimeType(fileName).toString();
              }
              if (contentType == null) {
                contentType = "TEXT/PLAIN";
              }
               // Microsoft rtf message's attachment, cannot deal with it
               if (contentType.toUpperCase().contains("MS-TNEF"))
                 {
                    meta.put("warning", fileName + "cannot be parsed");
                   continue;
                 }
              if (bodyPart.getFileName() != null) {
                System.out.println(bodyPart.getFileName());
                Node attachementNode = folderNode.addNode(bodyPart.getFileName(), "nt:file");
                Node resource = attachementNode.addNode("jcr:content", "nt:unstructured");
                resource.setProperty("jcr:data", bodyPart.getInputStream());
                bodyPart.getInputStream().close();
                resource.setProperty("jcr:lastModified", Calendar.getInstance());
                resource.setProperty("jcr:mimeType", contentType);
                System.out.println("mimetype=" + contentType);
              }

              Node messageNode = folderNode.addNode(messageName, "nt:file");
              Node contentNode = messageNode.addNode("jcr:content", "nt:unstructured");
              contentNode.setProperty("jcr:data", message);
              contentNode.setProperty("jcr:mimeType", messageContentType);

              for (String key : meta.keySet()) {
                if (meta.get(key)!= null)
                  contentNode.setProperty(key, meta.get(key).toString());
              }
              contentNode.setProperty("jcr:data", message);
              java.util.Calendar lastModified = java.util.Calendar.getInstance();
              contentNode.setProperty("jcr:lastModified", lastModified);
            }
          }

          if (i % 10 == 0 || i == count) {
            session.setAttribute("mm", "process status:" + session.getAttribute("cancel") + ";" + folder.getFullName() + ";" + i + " of total " + folder.getMessageCount() + "<br/>" + m.getSubject());
          }

        } catch (Exception e) {
          e.printStackTrace();
          break;
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      CloseUtil.close(folder);
      //jcrSession.logout();
    }
    try {
      Folder list[] = folder.list();
      for (Folder f : list) {
        //processMessage(f, session, jcrSession, remoteHost);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static String MungPass(String pass) throws NoSuchAlgorithmException {
    MessageDigest m = MessageDigest.getInstance("MD5");
    byte[] data = pass.getBytes();
    m.update(data, 0, data.length);
    BigInteger i = new BigInteger(1, m.digest());
    return String.format("%1$032X", i);
  }
%>